home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-03 | 8.1 KB | 255 lines | [TEXT/MPS ] |
- (* ****************************************************************
-
- IMid.p Translated to MPW Pascal by Jim Merritt (jam)
- based on an original C routine by Raymond Lau.
-
- Copyright © 1993 Aladdin Systems, Inc. & Raymond Lau.
- All Rights Reserved.
-
- In combination with the associated make file (IMid.make),
- this source text produces an IMid installer extension, which
- can be called by a Product Installer during the installation
- process. Specifications for IBeg, IMid, ICnd, and IEnd
- installer extensions are given in the documentation for
- StuffIt InstallerMaker™.
-
- In the absence of the folder manager (typically on System 6),
- this subroutine will:
-
- • Put any Aladdin folder within the :System:Extensions folder,
- creating the Extensions folder if necessary.
- • Put any file of types 'appe' or 'thng' into the
- :System:Extensions folder, creating the Extensions folder if
- necessary.
- • Put files of type 'Pref' and 'pref' into the :System:Preferences
- folder, creating the Preferences folder if necessary.
-
- CHANGE HISTORY:
-
- VER DATE ENGR DESCRIPTION
- 1 93.06.08 jam Initial version, based on Lau's
- original in C.
- 2 93.06.16 jam Pascal definitions of code resources were
- changed to replace BOOLEAN parameters and
- function return values with INTEGERs, and
- also to replace enumeration types and SETs
- with INTEGERs. This was made necessary
- when we discovered that certain Pascal
- compilers used very eccentric enumeration
- mechanisms, which were profoundly
- incompatible with the original C definitions
- at the machine-code level. The best
- compromise was to fall back to INTEGERs.
- 3 93.06.17 jam Introduced and made slight modifications to
- mag's routine, BlessedFldrSpec, replacing
- rl's original GetSysVolDir routine (from C
- version). Customers should compare
- GetSysVolDir and BlessedFolderSpec to see
- differences between low-level and higher-
- level coding to achieve the same ends.
-
- Rewrote code to change ensure that sense of
- FindFolderInSystem is always positive logic.
-
- 4 93.06.28 jam Changed to support 'thng' file type, per
- changes to Lau’s C version.
- 5 94.03.14 jam Changed DoWhileInstalling to support new
- "packages" parameter.
- 6 94.05.03 jam Changed DoWhileInstalling to support new
- "after" parameter.
-
- ****************************************************************** *)
- (*$Z+*) (* Allows linker to find DoWhileInstalling without declaring it
- in the interface *)
- UNIT IMid;
-
- INTERFACE (* empty -- see $Z directive, above *)
-
- IMPLEMENTATION
- (* Putting a subroutine within a UNIT that has an empty
- IMPLEMENTATION is an oft-used method for creating
- a standalone code-resource in MPW Pascal.
- *)
-
- (* *********************** INCLUDES *************************** *)
-
- USES Types,
- ToolUtils, (* for BitAnd *)
- Folders,
- OSUtils, (* for EqualString *)
- Files, (* for HParamBlockRec *)
- GestaltEqu (* for Gestalt *);
-
-
- CONST
- EmptyString= '';
-
- (* For using INTEGERs as if they were BOOLEANs *)
- IntFALSE= 0;
- IntTRUE= 1; (* (x <> IntFALSE) should be used to test for IntTRUE *)
- (* Use the constant IntTRUE only when you desire to assign a TRUE
- value to an INTEGER.
- *)
-
- (* Return and parameter values for various INTEGER items *)
- (* For ICnd, IMid *)
- OKToContinue= 0; (* For ICnd, IMid *)
- SkipThisItem= 1; (* For ICnd, IMid *)
- CancelInstallation= 2; (* For IMid only *)
-
- (* For IBeg, IEnd *)
- WasNOTAborted= 0;
- WasAborted= 1;
-
- (* FindFolderInSystem must be FORWARD because DoWhileInstalling MUST
- be the first routine that has a code body.
- *)
- FUNCTION FindFolderInSystem(name: str255; VAR vol: INTEGER;
- VAR dir: LongInt): BOOLEAN; FORWARD;
-
- FUNCTION DoWhileInstalling( userVol: INTEGER;
- userDir: LongInt;
- VAR destVol: INTEGER;
- VAR destDir: LongInt;
- isFolder: INTEGER;
- VAR name: Str255;
- creationDate: LongInt;
- modificationDate: LongInt;
- ftype, fcreator: OSType;
- packages: INTEGER;
- after: INTEGER): INTEGER;
-
- VAR
- gest: LongInt;
- result: INTEGER;
- BEGIN (* DoWhileInstalling *)
- result := OKToContinue;
- IF (after = IntFALSE) THEN BEGIN (* Only execute this BEFORE the file
- is installed. *)
- (* IF FindFolder is present THEN ... *)
- IF (Gestalt(gestaltFindFolderAttr,gest) <> noErr) (* does gestalt exist? *)
- THEN IF (NOT (BAND(gest,BitShift(1, gestaltFindFolderPresent)) <> 0))
- (* is the FindFolder avail bit set? *)
- THEN BEGIN
- IF (isFolder <> IntFALSE) THEN BEGIN
- IF (EqualString(name,'Aladdin',FALSE,TRUE)) THEN
- BEGIN
- IF (NOT FindFolderInSystem('Extensions', destVol, destDir))
- THEN result := CancelInstallation;
- (* If FindFolderInSystem succeeds, it changes destVol and
- destDir, thus redirecting the item under consideration
- to the specified folder. (In other words, the IMid
- changes the destination path before the Product
- Installer writes the item to the target.)
- *)
- END
-
- END ELSE BEGIN
- IF ((ftype = 'appe') OR (ftype = 'thng')) THEN BEGIN
- IF (NOT FindFolderInSystem('Extensions',destVol,destDir))
- THEN result := CancelInstallation;
- END ELSE IF ((ftype = 'Pref') OR (ftype = 'pref')) THEN BEGIN
- IF (NOT FindFolderInSystem('Preferences',destVol,destDir))
- THEN result := CancelInstallation;
- END;
- END;
-
- END;
- END (* Guard to make sure we are executing
- before the file is installed. *);
- DoWhileInstalling := result;
- END (* DoWhileInstalling *);
-
- FUNCTION BlessedFldrSpec ( VAR vRefNum: integer; VAR dirID: longint;
- VAR name: Str255 ): OSErr;
- (* Should take every possible way of finding the blessed folder.
- On ENTRY, values of vRefNum, dirID, and name are undefined.
- On EXIT,
- A return code of noErr, means that vRefNum, dirID and name
- contain a complete path specification for the blessed
- folder (not necessarily named 'System'!).
-
- Any other return code leaves the contents of vRefNum, dirID, and
- name undefined, and possibly altered from their entry states.
- *)
- CONST
- kSync= FALSE; (* call File System synchronously *)
- VAR
- theWorld: SysEnvRec;
- error: OSErr;
- wdpb: WDPBRec;
- cipb: CInfoPBRec;
-
- BEGIN (* BlessedFldrSpec *)
- name := EmptyString;
- vRefNum := 0;
- dirID := 0;
-
- error := SysEnvirons(1,theWorld);
-
- (* prepare wdpb for PBGetWDInfo *)
- wdpb.ioCompletion := NIL;
- wdpb.ioVRefNum := theWorld.sysVRefNum;
- wdpb.ioWDIndex := 0; (* use ioVRefNum *)
- wdpb.ioWDProcID := 0;
- wdpb.ioWDVRefNum := 0;
-
- wdpb.ioNamePtr := NIL; (* be clean about it *)
- wdpb.ioWDDirID := 0;
- wdpb.ioResult := noErr;
-
- error := PBGetWDInfo(@wdpb, FALSE);
-
- if (error = noErr)
- THEN BEGIN
- vRefNum := wdpb.ioWDVRefNum;
- dirID := wdpb.ioWDDirID;
-
- (* fill cipb for PBGetCatInfo *)
- cipb.ioCompletion := NIL;
- cipb.ioNamePtr := @name; (* File System fills this in *)
- cipb.ioVRefNum := vRefNum;
- cipb.ioFDirIndex := -1; (* get name using vRefNum, dirID *)
- cipb.ioDirID := dirID;
- error := PBGetCatInfo(@cipb, kSync);
-
- if (error <> noErr) THEN name := EmptyString;
- END;
-
- BlessedFldrSpec := error;
- END (* BlessedFldrSpec *);
-
- FUNCTION FindFolderInSystem(* name: str255; VAR vol: INTEGER;
- VAR dir: LongInt): BOOLEAN *);
- (* On ENTRY, if the specified system subfolder does not
- exist, routine attempts to create it.
- On EXIT, returns TRUE if the specified system subfolder
- exists, and FALSE if not (even despite attempts at
- creation). When TRUE, vol and dir specify the folder.
- *)
- VAR
- sysvol: INTEGER;
- sysdir: LongInt;
- HRec: HParamBlockRec;
- FFISname: Str255;
- FFISError: OSErr;
- BEGIN (* FindFolderInSystem *)
- FFISError := BlessedFldrSpec(sysvol, sysdir, FFISname);
- IF (FFISError <> noErr)
- THEN BEGIN FindFolderInSystem := FALSE
- END ELSE BEGIN
- HRec.ioNamePtr := @name;
- HRec.ioVRefNum := sysvol;
- HRec.ioDirID := sysdir;
- IF (PBDirCreateSync(@HRec) <> noErr) THEN BEGIN
- FindFolderInSystem := FALSE;
- END ELSE BEGIN
- vol := sysvol;
- dir := HRec.ioDirID;
- FindFolderInSystem := TRUE;
- END;
- END (* IF-THEN-ELSE *);
- END (* FindFolderInSystem *);
-
-
- END (* IMid *).